﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CodeGenerator.Core;
using System.IO;
using CodeGenerator.Common;
using System.Threading;
using Aspose.Cells;
using Aspose.Words;

namespace CodeGenerator.UI
{
    public partial class UcSetting : UserControl
    {
        public UcSetting()
        {
            InitializeComponent();
        }

        public BackgroundWorker doWorkChm=null;
        public BackgroundWorker doWorkHtml = null;
        public BackgroundWorker doWorkExcel = null;
        public BackgroundWorker doWorkWord = null;
        
        private void UcSetting_Load(object sender, EventArgs e)
        {
            lblMsg.ForeColor = Color.Red;
            MainSetting info = Config.GetSetupInfo();

            txtOutputDir.Text = info.OutputDir;
        }

        private void btnChoose_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            folderBrowserDialog.ShowDialog();
            txtOutputDir.Text = folderBrowserDialog.SelectedPath;
        }

        public void SetInfo(StringBuilder strInfo)
        {
            txtInfo.Text = strInfo.ToString();
        }

        public string GetOutputDir()
        {
            return txtOutputDir.Text;
        }

        public string GetDictType()
        {
            string result = "Word";
            if (radioButton1.Checked)
            {
                result= "Word";
            }
            else if (radioButton2.Checked)
            {
                result= "Excel";
            }
            else if (radioButton3.Checked)
            {
                result= "Html";
            }
            else if (radioButton4.Checked)
            {
                result= "Chm";
            }

            return result;
        }


        private string GetMsg(TableInfo table)
        {
            string tableName = string.Empty;
            if (!string.IsNullOrEmpty(table.Comments))
            {
                tableName = "(" + table.Comments.Replace("/", "") + ")";
            }

            tableName = ToChm.FormatString("<a href=\"表结构\\{0}{1}.html\">{0}</a>", new object[]
                        {
                            table.Name, 
                            tableName
                        });

            string empty = string.Empty;
            if (!string.IsNullOrEmpty(table.Comments))
            {
                empty = "(" + table.Comments.Trim().Replace("/", "").Replace("\"", "").Replace("\"", "") + ")";
            }

            return "已生成表结构..." + table.Name + empty;
        }
        #region Chm

        void doWorkChm_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //如果用户取消了当前操作就关闭窗口。
            if (e.Cancelled)
            {
                this.lblMsg.Text = "用户取消操作！！！";
                // this.ParentForm.Close();
            }
            else
            {
                this.lblMsg.Text = "执行完成！！！";
                doWorkChm.CancelAsync();
                this.ParentForm.Close();
            }

        }

        void doWorkChm_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //修改进度条的显示。
            this.progressBar1.Value = e.ProgressPercentage;

            string message = e.UserState.ToString();
            this.lblMsg.Text = message;
        }

        void doWorkChm_DoWork(object sender, DoWorkEventArgs e)
        {
            //在操作的过程中需要检查用户是否取消了当前的操作。
            if (doWorkChm.CancellationPending == true)
            {
                e.Cancel = true;
                return;
            }

            BackgroundWorker bgWorker = sender as BackgroundWorker;
            List<TableInfo> tables = new List<TableInfo>();
            if (e.Argument != null)
            {
                tables = (List<TableInfo>)e.Argument;
            }

            string defaultHtml = "数据库表目录.html";
            string folder = Guid.NewGuid().ToString();
            string dir = GetOutputDir();

            DirectoryInfo root_dict = Directory.CreateDirectory(Path.Combine(dir, folder)); // 根目录
            DirectoryInfo struct_dict = Directory.CreateDirectory(Path.Combine(dir, folder + "/表结构")); // 表结构
            DirectoryInfo data_dict = Directory.CreateDirectory(Path.Combine(dir, folder + "/表数据")); // 表数据

            ServerInfo serverInfo = Constant.CurrentServerInfo;
            serverInfo.DatabaseName = Constant.DatabaseName;
            IDatabase database = DBFactory.Database(serverInfo.DBType);

            DataTable dataTable = new DataTable();
            DataColumn dc = null;
            dc = dataTable.Columns.Add("序号", Type.GetType("System.Int32"));
            dc.AutoIncrement = true;//自动增加
            dc.AutoIncrementSeed = 1;//起始为1
            dc.AutoIncrementStep = 1;//步长为1
            dc.AllowDBNull = false;

            dataTable.Columns.Add("表名", typeof(String));
            dataTable.Columns.Add("表说明", typeof(String));


            int i = 0;
            foreach (var table in tables)
            {
                i++;

                string tableName = string.Empty;
                if (table.Comments != "")
                {
                    tableName = "(" + table.Comments.Replace("/", "") + ")";
                }

                tableName = ToChm.FormatString("<a href=\"表结构\\{0}{1}.html\">{0}</a>", new object[]
                        {
                            table.Name, 
                            tableName
                        });

                //新建行的赋值
                DataRow dr = dataTable.NewRow();
                dr[1] = tableName;
                dr[2] = table.Comments;
                dataTable.Rows.Add(dr);

                // 生成表结构
                DataTable tableStruct = DataHelper.ListToDataTable<ColumnInfo>(database.GetColumnInfoList(serverInfo, serverInfo.DatabaseName, table.Name));

                if (tableStruct != null && tableStruct.Rows.Count > 0)
                {
                    tableStruct.Columns.Remove("NetType");
                    tableStruct.Columns.Remove("JavaType");
                    tableStruct.Columns.Remove("IsNumeric");
                    tableStruct.Columns.Remove("IsDateTime");
                    tableStruct.Columns.Remove("IsBoolean");
                    tableStruct.Columns.Remove("UIControlType");

                    tableStruct.Columns["Id"].ColumnName = "序号";
                    tableStruct.Columns["Name"].ColumnName = "列名";
                    tableStruct.Columns["DataType"].ColumnName = "数据类型";
                    tableStruct.Columns["AutoIncrement"].ColumnName = "标识";
                    tableStruct.Columns["MaxLength"].ColumnName = "长度";
                    tableStruct.Columns["DecimalNum"].ColumnName = "小数位数";
                    tableStruct.Columns["DefaultValue"].ColumnName = "默认值";
                    tableStruct.Columns["AllowDBNull"].ColumnName = "允许空";
                    tableStruct.Columns["IsPrimaryKey"].ColumnName = "主键";
                    tableStruct.Columns["Comments"].ColumnName = "列说明";
                }

                string empty = string.Empty;
                if (table.Comments != "")
                {
                    empty = "(" + table.Comments.Trim().Replace("/", "").Replace("\"", "").Replace("\"", "") + ")";
                }

                ToChm.CreateHtml1(tableStruct, true, Path.Combine(struct_dict.FullName, table.Name + empty + ".html"), true, empty);

                bgWorker.ReportProgress(i, "已生成表结构..." + table.Name + empty);
            }

            dataTable.TableName = "<b>数据库表目录</b>";

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("正在生成数据库目录..." + defaultHtml);

            bgWorker.ReportProgress(i++, "正在生成数据库目录..." + defaultHtml);

            ToChm.CreateHtml1(dataTable, false, root_dict.FullName + "//" + defaultHtml, false, "");

            bgWorker.ReportProgress(i++, "正在打包数据字典");

            ChmHelper ChmHelper = new ChmHelper(Path.Combine(root_dict.FullName, "数据库表目录.html"), serverInfo.DatabaseName + ".chm", dir);

            bool flag = ChmHelper.Compile(root_dict.FullName);
            Directory.Delete(root_dict.FullName, true);
            File.Delete(Path.Combine(dir, "chm.hhc"));
            File.Delete(Path.Combine(dir, "chm.hhp"));
            File.Delete(Path.Combine(dir, "chm.hhk"));
        }

        public void GeneratorChm(IList<TableInfo> tables, string dir)
        {
            progressBar1.Minimum = 0;
            progressBar1.Maximum = tables.Count + 2;
            doWorkChm = new BackgroundWorker();
            doWorkChm.DoWork += doWorkChm_DoWork;
            doWorkChm.ProgressChanged += doWorkChm_ProgressChanged;
            doWorkChm.RunWorkerCompleted += doWorkChm_RunWorkerCompleted;
            doWorkChm.WorkerReportsProgress = true;//此属性必须设置，否则读取不到进度
            doWorkChm.WorkerSupportsCancellation = true; // 运行取消操作
            doWorkChm.RunWorkerAsync(tables);
        }
        
        #endregion

        #region Html
        void doWorkHtml_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //如果用户取消了当前操作就关闭窗口。
            if (e.Cancelled)
            {
                this.lblMsg.Text = "用户取消操作！！！";
                // this.ParentForm.Close();
            }
            else
            {
                this.lblMsg.Text = "执行完成！！！";
                doWorkHtml.CancelAsync();
                this.ParentForm.Close();
            }

        }

        void doWorkHtml_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //修改进度条的显示。
            this.progressBar1.Value = e.ProgressPercentage;

            string message = e.UserState.ToString();
            this.lblMsg.Text = message;
        }

        void doWorkHtml_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker bgWorker = sender as BackgroundWorker;
            List<TableInfo> tables = new List<TableInfo>();
            if (e.Argument != null)
            {
                tables = (List<TableInfo>)e.Argument;
            }

            ServerInfo serverInfo = Constant.CurrentServerInfo;
            serverInfo.DatabaseName = Constant.DatabaseName;
            IDatabase database = DBFactory.Database(serverInfo.DBType);

            string dir = GetFileName(serverInfo.DatabaseName, "html");

            StringBuilder str = new StringBuilder();
            str.Append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
            str.Append("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
            str.Append("<head>");
            str.Append("<title>【" + serverInfo.DatabaseName + "】数据库结构--BuildH自动生成（buildh.cn）-" + DateTime.Now + "</title>");
            str.Append("<style type=\"text/css\"> body { font-size: 9pt;} .styledb { font-size: 14px;}.styletab { font-size: 14px; padding-top: 15px; }a{text-decoration:none;}a:hover,a:active,a:focus{outline:none;text-decoration:none;} </style>");
            str.Append("</head>");
            str.Append("<body>");
            str.Append("<div style=\"text-align: center\">");
            str.Append("<div class=\"styledb\">数据库名：" + serverInfo.DatabaseName + "</div>");
            str.Append("<br />");
            str.Append("<br />");
            str.Append("<div class=\"styledb\"><a href='http://www.buildh.cn' target='_blank'>文档由BuildH代码生成器自动生成-" + DateTime.Now + "</a></div>");

            int i = 0;
            foreach (var table in tables)
            {
                i++;

                bgWorker.ReportProgress(i, GetMsg(table));

                str.Append("<div class=\"styletab\">表名：" + table.Name + "</div>");
                str.Append("<div align=\"left\">" + table.Comments + "</div>");
                str.Append("<div><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">");
                str.Append("<tr>");
                str.Append("<td bgcolor=\"#F5F9FF\">");
                str.Append("<table cellspacing=\"0\" cellpadding=\"5\" border=\"1\" width=\"100%\" bordercolorlight=\"#4F7FC9\" bordercolordark=\"#D3D8E0\">");
                str.Append("<tr bgcolor=\"#E3EFFF\"><td>序号</td><td>列名</td><td>数据类型</td><td>长度</td><td>小数位</td><td>允许空</td><td>默认值</td><td style=\"width:500px;\">说明</td><td>主键</td></tr>");
                str.Append("");

                str.Append("");
                str.Append("");

                List<ColumnInfo> columnInfo = database.GetColumnInfoList(serverInfo, serverInfo.DatabaseName, table.Name);

                foreach (ColumnInfo column in columnInfo)
                {
                    str.AppendFormat("<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td><td>{6}</td><td>{7}</td><td>{8}</td></tr>",
                        column.Id, column.Name, column.DataType, column.MaxLength, column.DecimalNum, column.AllowDBNull, column.DefaultValue, column.Comments, column.IsPrimaryKey);

                }
                str.Append("</table>");
                str.Append("</td>");
                str.Append("</tr>");
                str.Append("</table></div>");

                DirectoryUtil.Write(dir, str.ToString());
            }
        }

        public void GeneratorHtml(IList<TableInfo> tables)
        {

            progressBar1.Minimum = 0;
            progressBar1.Maximum = tables.Count;
            doWorkHtml = new BackgroundWorker();
            doWorkHtml.DoWork += doWorkHtml_DoWork;
            doWorkHtml.ProgressChanged += doWorkHtml_ProgressChanged;
            doWorkHtml.RunWorkerCompleted += doWorkHtml_RunWorkerCompleted;
            doWorkHtml.WorkerReportsProgress = true;//此属性必须设置，否则读取不到进度
            doWorkHtml.WorkerSupportsCancellation = true; // 运行取消操作
            doWorkHtml.RunWorkerAsync(tables);

        } 
        #endregion

        #region Excel
        Workbook workbook; //工作簿 

        void doWorkExcel_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //如果用户取消了当前操作就关闭窗口。
            if (e.Cancelled)
            {
                this.lblMsg.Text = "用户取消操作！！！";
                // this.ParentForm.Close();
            }
            else
            {
                this.lblMsg.Text = "执行完成！！！";
                doWorkExcel.CancelAsync();
                this.ParentForm.Close();
            }

        }

        void doWorkExcel_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //修改进度条的显示。
            this.progressBar1.Value = e.ProgressPercentage;

            string message = e.UserState.ToString();
            this.lblMsg.Text = message;
        }

        void doWorkExcel_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker bgWorker = sender as BackgroundWorker;
            List<TableInfo> tables = new List<TableInfo>();
            if (e.Argument != null)
            {
                tables = (List<TableInfo>)e.Argument;
            }

            ServerInfo serverInfo = Constant.CurrentServerInfo;
            serverInfo.DatabaseName = Constant.DatabaseName;
            IDatabase database = DBFactory.Database(serverInfo.DBType);

            string dir = GetFileName(serverInfo.DatabaseName, "xls");
           
            workbook = new Workbook(); // 创建工作簿
            ExcelTool.CreateIndexSheet(workbook, serverInfo.DatabaseName + "  数据库字典索引页");

            // 索引页行
            int indexrow = 0;
            foreach (var table in tables)
            {
                bgWorker.ReportProgress(indexrow, GetMsg(table));

                string strSheetName = !string.IsNullOrEmpty(table.Comments) ? table.Name + "【" + table.Comments + "】" : table.Name;

                ExcelTool.CreateWordAndLink(workbook, strSheetName, indexrow, 0);
                ExcelTool.CreateWorkSheets(workbook, "表信息", strSheetName, "#表索引!A" + (indexrow + 1));
                indexrow++;

                List<ColumnInfo> columnInfo = database.GetColumnInfoList(serverInfo, serverInfo.DatabaseName, table.Name);
                int i = 1;     // 序号
                int row = 2;   // 填充数据的行
                foreach (ColumnInfo column in columnInfo)
                {
                    ExcelTool.FillWorkSheetsDate(workbook, column, i);
                    row++;
                    i++;
                }
            }
            workbook.Save(dir);
        }


        /// <summary>
        /// 生成Excel数据字典
        /// </summary>
        /// <param name="server"></param>
        /// <param name="table_list"></param>
        public void GeneratorExcel(IList<TableInfo> tables)
        {
            progressBar1.Minimum = 0;
            progressBar1.Maximum = tables.Count;
            doWorkExcel = new BackgroundWorker();
            doWorkExcel.DoWork += doWorkExcel_DoWork;
            doWorkExcel.ProgressChanged += doWorkExcel_ProgressChanged;
            doWorkExcel.RunWorkerCompleted += doWorkExcel_RunWorkerCompleted;
            doWorkExcel.WorkerReportsProgress = true;//此属性必须设置，否则读取不到进度
            doWorkExcel.WorkerSupportsCancellation = true; // 运行取消操作
            doWorkExcel.RunWorkerAsync(tables);
        }

        
        #endregion

        #region Word
        void doWorkWord_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //如果用户取消了当前操作就关闭窗口。
            if (e.Cancelled)
            {
                this.lblMsg.Text = "用户取消操作！！！";
                // this.ParentForm.Close();
            }
            else
            {
                this.lblMsg.Text = "执行完成！！！";
                doWorkWord.CancelAsync();
                this.ParentForm.Close();
            }

        }

        void doWorkWord_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //修改进度条的显示。
            this.progressBar1.Value = e.ProgressPercentage;

            string message = e.UserState.ToString();
            this.lblMsg.Text = message;
        }

        void doWorkWord_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker bgWorker = sender as BackgroundWorker;
            List<TableInfo> tables = new List<TableInfo>();
            if (e.Argument != null)
            {
                tables = (List<TableInfo>)e.Argument;
            }

            ServerInfo serverInfo = Constant.CurrentServerInfo;
            serverInfo.DatabaseName = Constant.DatabaseName;
            IDatabase database = DBFactory.Database(serverInfo.DBType);

            string dir = GetFileName(Guid.NewGuid().ToString(), "html");

            StringBuilder str = new StringBuilder();
            str.Append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
            str.Append("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
            str.Append("<head>");
            str.Append("<title>【" + serverInfo.DatabaseName + "】数据库结构--BuildH自动生成（buildh.cn）-" + DateTime.Now + "</title>");
            str.Append("<style type=\"text/css\"> body { font-size: 9pt;} .styledb { font-size: 14px;}.styletab { font-size: 14px; padding-top: 15px; }a{text-decoration:none;}a:hover,a:active,a:focus{outline:none;text-decoration:none;} </style>");
            str.Append("</head>");
            str.Append("<body>");
            str.Append("<div style=\"text-align: center\">");
            str.Append("<div class=\"styledb\">数据库名：" + serverInfo.DatabaseName + "</div>");
            str.Append("<br />");
            str.Append("<br />");
            str.Append("<div class=\"styledb\"><a href='http://www.buildh.cn' target='_blank'>文档由BuildH代码生成器自动生成-" + DateTime.Now + "</a></div>");
            str.Append("<br />");

            int i = 0;
            foreach (var table in tables)
            {
                i++;

                bgWorker.ReportProgress(i, GetMsg(table));

                str.Append("<div class=\"styletab\">表名：" + table.Name + "</div>");
                str.Append("<div align=\"left\">" + table.Comments + "</div>");
                str.Append("<div><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">");
                str.Append("<tr>");
                str.Append("<td bgcolor=\"#F5F9FF\">");
                str.Append("<table cellspacing=\"0\" cellpadding=\"5\" border=\"1\" width=\"100%\" bordercolorlight=\"#4F7FC9\" bordercolordark=\"#D3D8E0\">");
                str.Append("<tr bgcolor=\"#E3EFFF\"><td>序号</td><td>列名</td><td>数据类型</td><td>长度</td><td>小数位</td><td>允许空</td><td>默认值</td><td style=\"width:500px;\">说明</td><td>主键</td></tr>");
                str.Append("");

                str.Append("");
                str.Append("");

                List<ColumnInfo> columnInfo = database.GetColumnInfoList(serverInfo, serverInfo.DatabaseName, table.Name);

                foreach (ColumnInfo column in columnInfo)
                {
                    str.AppendFormat("<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td><td>{6}</td><td>{7}</td><td>{8}</td></tr>",
                        column.Id, column.Name, column.DataType, column.MaxLength, column.DecimalNum, column.AllowDBNull, column.DefaultValue, column.Comments, column.IsPrimaryKey);

                }
                str.Append("</table>");
                str.Append("</td>");
                str.Append("</tr>");
                str.Append("</table></div>");

                DirectoryUtil.Write(dir, str.ToString());
            }
            i++;
            bgWorker.ReportProgress(i, "正在转换word文档...");
            string newDir = GetFileName(serverInfo.DatabaseName, "doc");
            new Document(dir).Save(newDir, Aspose.Words.SaveFormat.Doc);
            i++;
            bgWorker.ReportProgress(i, "清理临时文件...");
            System.Threading.Thread.Sleep(1000);
            DirectoryUtil.DeleteFile(dir);
        }

        public void GeneratorWord(IList<TableInfo> tables)
        {

            progressBar1.Minimum = 0;
            progressBar1.Maximum = tables.Count+2;
            doWorkWord = new BackgroundWorker();
            doWorkWord.DoWork += doWorkWord_DoWork;
            doWorkWord.ProgressChanged += doWorkWord_ProgressChanged;
            doWorkWord.RunWorkerCompleted += doWorkWord_RunWorkerCompleted;
            doWorkWord.WorkerReportsProgress = true;//此属性必须设置，否则读取不到进度
            doWorkWord.WorkerSupportsCancellation = true; // 运行取消操作
            doWorkWord.RunWorkerAsync(tables);

        }
        #endregion

        #region 私有文件名
        private string GetFileName(string fileName, string extension,int i=0)
        {
            string fileNamePath= string.Empty;
            if(i<=0)
            {
                fileNamePath = GetOutputDir() + "\\" + fileName + "." + extension;
            }
            else
            {
                fileNamePath = GetOutputDir() + "\\" + fileName + "("+i+")." + extension;
            }
            if (DirectoryUtil.IsExistFile(fileNamePath))
            {
                i++;
                return GetFileName(fileName, extension, i);
            }
            else
            {
                return fileNamePath;
            }
        }
        #endregion
    }
}
